# 线程池适用：大量新建线程且任务处理时间短、或突发大量请求
# 重用线程资源，避免创建线程过多而导致系统负荷大响应变慢

import concurrent.futures
from Thread_example import spider  # 导入Thread中的spider
# craw  线程池第一种写法map函数   写法简单，结果顺序与入参顺序对应
with concurrent.futures.ThreadPoolExecutor() as pool:

    htmls = pool.map(spider.craw, spider.urls)  # 参数为列表形式，适合所有参数一次传入    # map错误，找不到map函数
    htmls = list(zip(spider.urls, htmls))
    for url, html in htmls:
        print(url, len(html))
# pool = concurrent.futures.ThreadPoolExecutor()
# htmls = pool.map(spider.craw, spider.urls)
# htmls = list(zip(spider.urls, htmls))

# for url, html in htmls:
#     print(url, len(html))

print("craw over")

# parse 线程池第二种写法future模式   更加强大，写法较复杂
with concurrent.futures.ThreadPoolExecutor() as pool:
    futures = {}  # 字典
    for url, html in htmls:
        future = pool.submit(spider.parse, html)  # 传入单个html
        futures[future] = url  # future表示key

    # for future, url in futures.items(): # 结果顺序打印
    #     print(url, future.result())

    # 结果不一定 哪个先结束哪个先返回
    for future in concurrent.futures.as_completed(futures):  # 遍历futures字典
        url = futures[future]  #
        print(url, future.result())

print("parse over")
